from datetime import timedelta
from flask_cors import CORS
from flask import Flask, Blueprint, Response, request, send_from_directory, url_for, make_response, send_file
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity, get_jwt

from app.config.db import DBUtils
from app.controller.loginController import login_bp
from app.controller.UserPortraitController import user_portrait_bp
from app.controller.SearchController import search_bp
from app.controller.OpponentCharactersController import opponent_characters_bp
from app.controller.TransactionCharactersController import transaction_characters_bp
from app.controller.SettlementPreferenceController import settlement_preference_bp
from app.controller.portraitJyfxSffxTabController import portrait_jyfx_sffx_tab_up
from app.controller.capitalRiskController import capital_risk_up
from app.controller.tradeGraphController import trade_features_up
from app.controller.wareHouseController import ware_house_up
from app.controller.businessRiskController import business_risk_up
from app.controller.reportGenerationController import sys_report_bp
from app.controller.RiskHistoryController import risk_history_bp
from app.controller.CalculationController import calcu_result
from app.common.commonMessage import CommonMassages

import os,json

from app.service.SysReportService import SysReportService

app = Flask(__name__, static_folder='../static')

# 注册蓝图
app.register_blueprint(login_bp)
app.register_blueprint(user_portrait_bp)
app.register_blueprint(search_bp)
app.register_blueprint(opponent_characters_bp)
app.register_blueprint(transaction_characters_bp)
app.register_blueprint(settlement_preference_bp)
app.register_blueprint(portrait_jyfx_sffx_tab_up)
app.register_blueprint(capital_risk_up)
app.register_blueprint(trade_features_up)
app.register_blueprint(business_risk_up)
app.register_blueprint(ware_house_up)
app.register_blueprint(sys_report_bp)
app.register_blueprint(risk_history_bp)
app.register_blueprint(calcu_result)

# 处理跨域
CORS(app)

# 设置密钥，用于JWT加密和解密
app.config['JWT_SECRET_KEY'] = 'ldzjsmy114514'  # 密钥
# 设置访问令牌的过期时间为24小时
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=12)
app.config['JWT_BLACKLIST_ENABLED'] = True
app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh']

jwt = JWTManager(app)

project_root = os.path.dirname(os.path.abspath(__file__))
TMP_FOLDER = os.path.join(project_root, 'app', 'static', 'tmp')
REPORT_FOLDER = os.path.join(project_root, 'app', 'static', 'output')

# 创建一个黑名单集合来存储失效的令牌（一般可用数据库来代替）
blacklist = set()

sysReport = SysReportService()

# 获取session
db_utils = DBUtils()
session = db_utils.get_session()

# 定义检查令牌是否在黑名单中的回调函数
@jwt.token_in_blocklist_loader
def check_if_token_in_blacklist(jwt_header, jwt_payload):
    jti = jwt_payload['jti']
    return jti in blacklist

# 退出登录
@app.route('/loginout', methods=['POST'])
@jwt_required()
def loginout():
    # 获取当前JWT的唯一标识符（jti）
    jti = get_jwt()['jti']
    blacklist.add(jti)
    respResult = {
        "code": 200,
        "data": None,
        "message": CommonMassages.USER_LOGINOUT_SUCCESS.value
    }
    resp_data = json.dumps(respResult, ensure_ascii=False)
    return Response(resp_data, content_type='application/json')


# 自定义处理JWT过期的回调函数
@jwt.expired_token_loader
def expired_token_callback(jwt_header, jwt_payload):
    respResult = {
        "code": 401,
        "data": None,
        "message": CommonMassages.TOKEN_EXPIRED_ERROR.value
    }
    resp_data = json.dumps(respResult, ensure_ascii=False)
    return Response(resp_data, content_type='application/json')

# 下载报告文件
@app.route('/kshx/download-reportfile', methods=['GET'])
@jwt_required()
def download_reportfile():
    uuid = request.args.get('uuid')
    filename = sysReport.select_file_by_uuid(session, uuid)
    file_path = os.path.join(REPORT_FOLDER, filename)
    return send_file(
        file_path,
        as_attachment=True,
        download_name=filename,
        mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    )

# 下载模板文件
@app.route('/kshx/download-hshtplfile', methods=['GET'])
@jwt_required()
def download_hshtplfile():
    filename = "kshx_hsh_tpl.xlsx"
    file_path = os.path.join(TMP_FOLDER, filename)
    return send_file(
        file_path,
        as_attachment=True,
        download_name=filename,
        mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    )

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9000)